#include<bits/stdc++.h>
using namespace std;
#define all(x) (x).begin(),(x).end()
#define rall(x) (x).rbegin(),(x).rend()
const int N=1e5+10;//数据规模
#define INF 0x3f3f3f3f;
typedef long long int ll;
#define close(); std::ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);
//----------------------------------------------------------------------------//
int e[N],ne[N],h[N],idx;//单链表，详见add  <公司人际关系> 
int happy[N];//存快乐值 
int n;//有n个人 
bool has_fa[N];//判断某人有没有上司 
int f[N][2];
//f[u][1]:以u为根节点的子树并且包括u的总快乐指数，
//f[u][0]:以u为根节点并且不包括u的总快乐指数;
void add(int a,int b)//邻接表建图 
{
    e[idx]=b,ne[idx]=h[a],h[a]=idx,idx++;  
}
//节点的编号是指上图所画的树中节点的值，范围是从1~n。在本题中，每次输入的a和b就是节点的编号，编号用e[i]数组存储。
//节点的下标指节点在数组中的位置索引，数组之间的关系就是通过下标来建立连接，下标用idx来记录。idx范围从0开始，如果idx==-1表示空(公司里全是鬼)-->新算法题《人都没有的舞会》。
//ne[i]的值是下标，是下标为i的节点的next节点的下标，ne[i]=-1表示该表已被遍历完。
//h[i]存储的是下标，是编号为i的节点的next节点的下标，表示以i为头节点的子树。
void dfs(int u)//递归每一个点 ，u为点的编号 
{
    f[u][1]=happy[u];//该boss要来，此时快乐值至少为该boss的快乐值 
    for(int i=h[u]/*取出头节点*/;i!=-1/*一直找到这条单链表为空*/;i=ne[i]/*下一个与u所连点的下标，实现遍历*/)//从头节点开始遍历邻接表 
    {
        int j=e[i];//取出相连点所存的值 （点的编号） 
        dfs(j);//用该值开始新遍历
        f[u][1]+=f[j][0];//u是j的上司，存在领导关系，所以一定不能让j来<boss归来，小弟承让> 
        f[u][0]+=max(f[j][0],f[j][1]);//u可以作为j和u的上司的中间人，j来不来都可以 <boss不在，小弟为王，小弟来与否？> 
    }
    //这里可以不写return，上方循环肯定不是死循环且遍历终有尽时，在一切执行完之后自动return 
}
int main()//主函数 
{
    scanf("%d",&n);//输入n<舞会积极报名中> 
    for(int i=1;i<=n;i++) cin>>happy[i];//输入快乐值 
    memset(h,-1,sizeof h);//头节点数组初始化为-1（每个点都无相连接的点） 
    for(int i=n+1;i<2*n;i++)
    {
        int a,b;//a是b的上司 
        scanf("%d %d",&b,&a);//输入上司关系 
        has_fa[b]=true;//确认b有上司<是个打工人> 
        add(a,b);//加边建树 
    }
    int root=1;//赋头节点初值（最小为1（公司至少有一个人吧）） 
    while (has_fa[root])root++;//找到没有上司的节点，即为根节点<公司大boss> 
    dfs(root);//从根节点开始dfs遍历 
    printf("%d\n", max(f[root][0],f[root][1]));//比较头节点的两种方案 <大oss到底来不来好>
    //<舞会的开始> 
    return 0;//结束程序 <舞会的结束> 
}

